#include "mock_caller.h"
#include <iostream>
#include <chrono>

#include "Dummy_struct.h"
#include "Data_struct.h"

using namespace std::chrono;

std::time_t getMillionSeconds() {
    auto now = system_clock::now();
    auto millionSecondsDuration = duration_cast<milliseconds>(now.time_since_epoch());
    return millionSecondsDuration.count();
}

MockCaller::MockCaller() {
    tick_ = getMillionSeconds();
}

MockCaller::~MockCaller() {
}

void MockCaller::doTest(rpc::TransportPtr trans, rpc::Rpc* rpc) {
    if (!trans && !trans_) {
        return;
    }

    if (!rpc) {
        return;
    }

    if (!trans_) {
        trans_ = trans;
    }
    if (!finished_) {
        return;
    }
    finished_ = false;
    if (!prx_) {
        // Create a proxy for 'Service'
        prx_ = rpc::createProxy<ServiceProxy>(trans_, true, rpc);
    }
    if (!prxDy_) {
        // Create a proxy for 'ServiceDynamic'
        prxDy_ = rpc::createProxy<ServiceDynamicProxy>(trans_, true, rpc);
    }
    // Call a notification method of Service::method1
    prx_->method1({}, "");
    // Call a notification method of ServiceDynamic::method1
    prxDy_->method1({}, "");
    co (
        //
        // Call 8 method in a coroutine, Each method is syncronized method will waiting for service's return
        //
        auto s = prx_->method2(1, {}, 1);
        auto m = prx_->method3(1, {}, {}, 1);
        prx_->method4();
        prx_->method5();
        s = prxDy_->method2(1, {}, 1);
        m = prxDy_->method3(1, {}, {}, 1);
        prxDy_->method4();
        prxDy_->method5();
        // Statistics data
        count_ += 10;
        if (count_ % 10000 == 0) {
            auto tick = getMillionSeconds();
            auto gap = tick - tick_;
            tick_ = tick;
            auto ratio = 1000.0 / (float)gap;
            std::cout << "rpc call count 10000" << " in " << gap << "(ms)" << "," << (float)10000 / (float)gap << "(n/ms)" << "," << 10000.0 * ratio << "(n/s)" << std::endl;
	    } 
        finished_ = true;
    )
}

